class TaskManager {
public:
    TaskManager(vector<vector<int>>& tasks) {
        for (auto& task : tasks)
            add(task[0], task[1], task[2]);
    }

    void add(int userId, int taskId, int priority) {
        _pt.push({ priority, taskId });
        _hashtp[taskId] = priority;
        _hashtu[taskId] = userId;
    }

    void edit(int taskId, int newPriority) {
        _pt.push({ newPriority, taskId });
        _hashtp[taskId] = newPriority;
    }

    void rmv(int taskId) {
        _hashtu[taskId] = -1;
        _hashtp[taskId] = -1;
    }

    int execTop() {
        while (_pt.size()) {
            auto a = _pt.top();
            _pt.pop();
            if (_hashtp[a.second] == -1) continue;
            else if (_hashtp[a.second] == a.first) {
                int ret = _hashtu[a.second];
                rmv(a.second);
                return ret;
            }
        }
        return -1;
    }
private:
    priority_queue<pair<int, int>> _pt;
    unordered_map<int, int> _hashtu;
    unordered_map<int, int> _hashtp;
};

/**
 * Your TaskManager object will be instantiated and called as such:
 * TaskManager* obj = new TaskManager(tasks);
 * obj->add(userId,taskId,priority);
 * obj->edit(taskId,newPriority);
 * obj->rmv(taskId);
 * int param_4 = obj->execTop();
 */